/*
 * ==================================================
 * 项目开发者：JerryStark
 * 开发者Email：4771007@qq.com
 * 开发者QQ:4771007
 * 开发范围：web，wap，android,ios,osx or win or linux 应用
 * ==================================================
 */
package RTGame.Server;

import RTGame.Configs.Load;
import RTPower.RTMD5;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 端口消息回复类
 * <br>对客户端传入的消息统一进行处理
 * <br>全部经过md5加密验证,没有通过则回错
 * <br>统一采用json格式回复
 *
 * @author jerry
 */
public class WriteBack {

    /**
     * 客户端ip
     */
    public String ClientIp;
    /**
     * 客户端msg字符串
     */
    public JsonObject ClientMsg = new JsonObject();

    /**
     * 服务器token
     */
    public String ServerToken;

    /**
     * 初始化解析数据
     *
     * @param client_ip 客户端ip
     * @param client_msg
     */
    public WriteBack(String client_ip, StringBuilder client_msg) {
        ServerToken = Load.MainConfig.get("Token").getAsString();
        ClientIp = client_ip;
        ScanClientUrl(client_msg.toString());

    }

    /**
     * 返回服务器端处理完毕的数据给客户端
     *
     * @return
     */
    public String BackMsg() {
        //签名错误直接停止
        if (!ScanSign()) {
//            return Action.BackJsonMsg("error", "签名错误", null);
        }
        //根据不同的action 来执行不同的方法

        return ScanAction();
    }

    /**
     * 解析url
     * <br>格式GET GET /?sss=ss HTTP/1.1
     *
     * @param msg
     * @return
     */
    private void ScanClientUrl(String msg) {

        //以空格分割
        String[] msg_split = msg.split(" ");
        //如果空格分割小于2 则没有正确获得
        if (msg_split.length < 2) {
            return;
        }
        //得到完整的url
        String all_url = msg_split[1];

        //再切割出参数和值
        String[] use_param_string = all_url.split("\\?");
        if (use_param_string.length < 2) {
            return;
        }

        String all_param_string = use_param_string[1];

        //开始以&号来分割
        String[] param_split = all_param_string.split("\\&");
        for (int i = 0; i < param_split.length; i++) {
            String one_string = param_split[i];
            //分割出key和value
            String[] one_param = one_string.split("\\=");
            String one_key = one_param[0];
            String one_value = "";
            if (one_param.length > 1) {
                one_value = one_param[1];
            }
            //添加进键值对
            ClientMsg.addProperty(one_key, one_value);
        }
    }

    /**
     * 验证加密签名是否正确
     * <br>验证方法:MD5(action+key+ip)
     *
     * @return false 验证失败 true 验证成功
     */
    private boolean ScanSign() {

        if (ClientMsg.entrySet().isEmpty()) {
            return false;
        }
        if (!ClientMsg.has("sign")) {
            return false;
        }
        String client_sign = ClientMsg.get("sign").getAsString();
        String client_action = ClientMsg.get("action").getAsString();

        String server_sign = RTMD5.MD5(client_action + ServerToken + ClientIp);
//        System.err.println("客户机sign:" + client_sign);
//        System.err.println("服务器sign:" + server_sign);
        //检查是否一致
        return client_sign.toLowerCase().equals(server_sign.toLowerCase());
    }

    /**
     * 扫描action,根据不同的类型处理不同的任务
     * <br>采用映射
     *
     * @return
     */
    private String ScanAction() {

        //获取action
        String client_action = ClientMsg.get("action").getAsString();

        try {
            Class<?> c = Class.forName("RTGame.Server.Action");
            Object obj = c.newInstance();
            //第一个参数写的是方法名,第二个\第三个\...写的是方法参数列表中参数的类型
            Method method = c.getMethod(client_action, JsonObject.class);
            //invoke是执行该方法,并携带参数值
            String str2;
            try {
                str2 = (String) method.invoke(obj, ClientMsg);
                return str2;

            } catch (IllegalArgumentException | InvocationTargetException ex) {
                Logger.getLogger(WriteBack.class.getName()).log(Level.SEVERE, null, ex);
            }

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException ex) {
            return Action.BackJsonMsg("error", "action不存在", null);
        }

        return Action.BackJsonMsg("error", "未知错误", null);
    }
}
